﻿using System;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using DevExpress.Xpf.Ribbon;
using Loki.Commands;
using Loki.Utils;

namespace Loki.UI.Wpf
{
    /// <summary>
    /// Logique d'interaction pour ViewWindow.xaml
    /// </summary>
    public partial class ViewWindow : DXRibbonWindow, IView
    {
        #region Log
        /// <summary>
        /// Gets the logger name ; must be redefined in derived classes.
        /// </summary>
        protected virtual string LoggerName
        {
            get
            {
                if (_LoggerName == null)
                {
                    _LoggerName = this.GetType().FullName;
                }

                return _LoggerName;
            }
        }

        private string _LoggerName = null;

        private ILog _Log = null;

        /// <summary>
        /// Gets the logger.
        /// </summary>
        /// <value>The logger.</value>
        protected ILog Log
        {
            get
            {
                if (_Log == null)
                {
                    Interlocked.CompareExchange(ref _Log, LokiServices.Logger.GetLogger(LoggerName), null);
                }

                return _Log;
            }
        }
        #endregion

        private CommandManager _Commands;

        public ViewWindow()
        {
            this.Loaded += ViewWindow_Loaded;
            this.Activated += ViewWindow_Activated;
            this.Deactivated += ViewWindow_Deactivated;
            this.Closing += ViewWindow_Closing;

            this.DataContextChanged += ViewWindow_DataContextChanged;

            _Commands = new CommandManager();
        }

        void ViewWindow_Closing(object sender, CancelEventArgs e)
        {
            _IsClosing = true;
            if (ViewModel != null)
            {
                ViewModel.Close.Execute(null);
            }
        }

        void ViewWindow_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (ViewModel != null)
            {
                _Commands.Handle(ViewModel.Close, ViewModel_CanClose, ViewModel_Close);
                ViewModel.Initialize();
            }
        }

        protected virtual void ViewModel_CanClose(object sender, CanExecuteCommandEventArgs e)
        {
            e.CanExecute = !_IsClosing;
        }

        private bool _IsClosing = false;

        protected virtual void ViewModel_Close(object sender, CommandEventArgs e)
        {
            this.Close();
        }

        void ViewWindow_Deactivated(object sender, EventArgs e)
        {
            Log.DebugFormat("View {0} desactivated", Title);
            ViewModel.Desactivate.Execute(null);
        }

        void ViewWindow_Activated(object sender, EventArgs e)
        {
            Log.DebugFormat("View {0} activated", Title);
            ViewModel.Activate.Execute(null);
        }

        void ViewWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            ViewModel.LoadData();
        }

        public IViewModel ViewModel
        {
            get
            {
                return DataContext as IViewModel;
            }
            set
            {
                DataContext = value;
            }
        }

        #region Disposed
        public event EventHandler Disposed;

        protected virtual void OnDisposed(EventArgs e)
        {
            EventHandler L_Handler = Disposed;

            if (L_Handler != null)
            {
                L_Handler(this, e);
            }
        }

        #endregion

        /// <summary>
        /// Releases all resources used by an instance of the <see cref="ViewWindow" /> class.
        /// </summary>
        /// <remarks>
        /// This method calls the virtual <see cref="Dispose(bool)" /> method, passing in <strong>true</strong>, and then suppresses 
        /// finalization of the instance.
        /// </remarks>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
            OnDisposed(EventArgs.Empty);
        }

        ~ViewWindow()
        {
            Dispose(false);
        }

        /// <summary>
        /// Releases the unmanaged resources used by an instance of the <see cref="ViewWindow" /> class and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing"><strong>true</strong> to release both managed and unmanaged resources; <strong>false</strong> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_Commands != null)
                {
                    _Commands.Dispose();
                }
            }
        }
    }
}
